package cn.ztydata.teachingsystem.heaven.service;

import cn.ztydata.teachingsystem.common.Page;
import cn.ztydata.teachingsystem.exception.ServiceException;
import cn.ztydata.teachingsystem.heaven.common.WebContext;
import cn.ztydata.teachingsystem.heaven.cons.Roles;
import cn.ztydata.teachingsystem.heaven.dao.AnswerDao;
import cn.ztydata.teachingsystem.heaven.dao.CourseGroupDao;
import cn.ztydata.teachingsystem.heaven.dao.QuestionDao;
import cn.ztydata.teachingsystem.heaven.dao.redis.QuestionPvAnCountDao;
import cn.ztydata.teachingsystem.heaven.entity.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 问题业务类
 *
 * @author lyj
 * @since 2015-3-19
 */
@Service
public class QuestionService extends BaseService{
    @Autowired
    private WebContext webContext;
    @Autowired
    private QuestionDao questionDao;
    @Autowired
    private AnswerDao answerDao;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private QuestionPvAnCountDao questionPvAnCountDao;
    @Autowired
    private CourseGroupDao courseGroupDao;

    /**
     * 验证权限
     *
     * @param questionId 问题ID
     * @return boolean
     * @author lyj
     * @since 2015-3-26
     */
    public boolean checkRole(final long questionId) {

        //判断登录用户是否为问题创建人
        if (questionDao.checkCreator(questionId) == 1) {
            log.debug("判断登录用户是否为问题创建人questionDao.checkCreator(questionId) == 1");
            return true;
        }

        if (webContext.getRole() != Roles.STUDENT) {
            //判断问题所在课程群组是否为老师所管理的课程群组
            if (questionDao.checkGroup(questionId) == 1) {
                log.debug("判断问题所在课程群组是否为老师所管理的课程群组questionDao.checkGroup(questionId) == 1");
                return true;
            }
        }
        log.debug("验证权限");
        return false;
    }


    /**
     * 新增问题
     *
     * @param question 问题实体
     * @return void
     * @author lyj
     * @since 2015-3-19
     */
    public void addQuestion(Question question) {
        if (webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT) {
            throw new ServiceException("权限错误！");
        }

        //新增问题
        if (questionDao.addQuestion(question) != 1) {
            log.debug("新增问题questionDao.addQuestion(question) != 1");
            log.warn("新增问题失败!");
            throw new ServiceException("新增问题失败!");
        }
    }


    /**
     * 编辑问题
     *
     * @param question 问题实体

     * @return void
     * @author lyj
     * @since 2015-3-19
     */
    public void editQuestion(Question question) {

        if (webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT) {
            throw new ServiceException("权限错误！");
        }

        if (!checkRole(question.getId())) {
            throw new ServiceException("权限错误或问题已经被删除！");
        }

        //验证问题是否可编辑（如果没有设为精选可以编辑，没有解决可以编辑。问题的创建人可以编辑）
        if (questionDao.checkQuestion(question.getId()) != 1) {
            log.debug("验证问题是否可编辑（如果没有设为精选可以编辑，没有解决可以编辑。问题的创建人可以编辑）questionDao.checkQuestion(question.getId()) != 1");
            log.warn("权限错误！");
            throw new ServiceException("权限错误！");
        }

        //编辑问题
        if (questionDao.editQuestion(question) != 1) {
            log.debug("编辑问题questionDao.editQuestion(question) != 1");
            log.warn("编辑问题失败: id->{}", question.getId());

            throw new ServiceException("编辑问题失败");
        }
    }


    /**
     * 设为精选问题
     *
     * @param question 问题实体
     * @return void
     * @author lyj
     * @since 2015-3-19
     */
    public void setChoiceness(Question question){
        if (webContext.getRole() != Roles.TEACHER) {
            log.debug("如果登录用户是学生（只有老师能设置精选）webContext.getRole() == Roles.STUDENT");
            log.warn("学生没有权限执行设置精选操作！userId->{}", webContext.getUserId());
            throw new ServiceException("权限错误！");
        }

        //验证登录用户是否可以设置该问题为精选问题（判断问题所在课程群组是否为老师所管理的课程群组）
        if(questionDao.checkGroup(question.getId()) != 1){
            log.debug("验证登录用户是否可以设置该问题为精选问题（判断问题所在课程群组是否为老师所管理的课程群组）questionDao.checkGroup(question.getId()) != 1");
            log.warn("权限错误！");
            throw new ServiceException("该问题已经删除或权限错误！");
        }

        if (questionDao.setChoiceness(question) != 1){
            log.debug("设置精选questionDao.setChoiceness(question) != 1");
            log.warn("设为精选失败: id->{}", question.getId());
            throw new ServiceException("设置精选失败");
        }
    }


    /**
     * 删除问题
     *
     * @param id 问题ID
     * @return void
     * @author lyj
     * @since 2015-3-19
     */
    @Transactional
    public void deleteQuestion(final long id) {

        if (webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT) {
            throw new ServiceException("权限错误！");
        }

        //验证权限
        if (!checkRole(id)){
            log.debug("验证权限!checkRole(id)");
            log.warn("权限错误！");
            throw new ServiceException("该问题已经删除或权限错误！");
        }


        //删除问题
        if (questionDao.deleteQuestion(id) != 1) {
            log.debug("删除问题questionDao.deleteQuestion(id) != 1");
            log.warn("删除问题失败: id->{}", id);
            throw new ServiceException("删除失败！");
        }

        //删除问题答案
        answerDao.deleteAnswerByQueId(id);


    }


    /**
     * 获取问题明细
     *
     * @param id 问题ID
     * @return Question
     * @author lyj
     * @since 2015-3-19
     */
    public Question getDetail(final long id, final String num, final long groupId){
        if (webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT) {
            throw new ServiceException("权限错误！");
        }
        //判断登录用户是否可以获取该课程群组信息
        if (courseGroupDao.checkGroupIdIsNum(groupId, num) == 0) {
            throw new ServiceException("权限错误！");
        }

        Question question = questionDao.getDetail(id);

        if (question == null){
            log.debug("question == null");
            throw new ServiceException("获取明细失败！");
        }

        //递增问题浏览量
        questionPvAnCountDao.increment(id, questionPvAnCountDao.VIEWS, 1);

        //获取问题浏览量和回答量(返回值顺序和传入参数顺序一致)
        List<Long> counts = questionPvAnCountDao.getCount(id, questionPvAnCountDao.VIEWS, questionPvAnCountDao.ANSWER_COUNT);
        question.setPv(counts.get(0)); //绑定浏览量
        question.setAnswerCount(counts.get(1)); //绑定回答量

        //存储创建人ID
        Set<Long> creatorId = new HashSet<>();
        creatorId.add(question.getCreatorId());

        //如果创建人角色为老师
        if (question.getRole() == 0){
            log.debug("如果创建人角色为老师question.getRole() == 0");
            //获取教师头像、姓名
            Map<Long, Teacher> reTeacher = teacherService.getPictures(creatorId);

            //绑定教师头像和姓名
            question.setCreatorName(reTeacher.get(question.getCreatorId()).getName());
            question.setCreatorPhoto(reTeacher.get(question.getCreatorId()).getPicture());

        } else { //如果创建人角色为学生

            log.debug("如果创建人角色为学生");
            //获取学生头像、姓名
            Map<Long, Student> reStudent = studentService.getPictures(creatorId);

            //绑定学生头像和姓名
            question.setCreatorName(reStudent.get(question.getCreatorId()).getName());
            question.setCreatorPhoto(reStudent.get(question.getCreatorId()).getAvatar());
        }

        log.debug("获取问题明细");
        return question;

    }


    /**
     * 问题列表
     *
     * @param groupId 群组ID
     * @param tag 标记(0全部1精选2已解决3待解决4我的)
     * @param pageNum 当前页码
     * @param pageSize 每页条数
     * @return page
     * @author lyj
     * @since 2015-3-20
     */
    public Page<Question> getList(final long groupId,  final int tag, final int pageNum, final int pageSize, final User userInfo){

        if (webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT) {
            throw new ServiceException("权限错误！");
        }

        //判断登录用户是否可以获取该课程群组信息
        if (courseGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
            throw new ServiceException("权限错误！");
        }

        int choiceness = 2; //是否为精选（0非精选 1精选）
        int status = 2; //是否解决（0待解决 1已解决）
        long creatorId = 0; //创建人ID

        if (tag == 1){
            log.debug("tag == 1");
            choiceness = 1;
        } else if (tag == 2){
            log.debug("tag == 2");
            status = 1;
        } else if (tag == 3){
            log.debug("tag == 3");
            status = 0;
        } else if (tag == 4){
            log.debug("tag == 4");
            creatorId = webContext.getUserId();
        }

        Page<Question> page = questionDao.getList(groupId, choiceness, status, creatorId, pageNum, pageSize);

        //存储老师ID
        Set<Long> teacherIds = new HashSet<>();
        //存储学生ID
        Set<Long> studentIds = new HashSet<>();

        if (page.getItems().size() == 0){
            log.debug("如果为空page.getItems().size() == 0");
            return page;
        }

        //循环读取创建人ID
        log.debug("循环读取创建人ID");
        for (Question question : page.getItems()){
            if (question.getRole() == 0){
                teacherIds.add(question.getCreatorId());
            } else {
                studentIds.add(question.getCreatorId());
            }
        }

        //获取教师头像、姓名
        Map<Long, Teacher> reTeacher = teacherService.getPictures(teacherIds);
        //获取学生头像、姓名
        Map<Long, Student> reStudent = studentService.getPictures(studentIds);


        //循环绑定头像和姓名、浏览量、回答量
        log.debug("循环绑定头像和姓名、浏览量、回答量");
        for (Question question : page.getItems()){
            if (question.getRole() == 0) {
                log.debug("question.getRole() == 0");
                question.setCreatorName(reTeacher.get(question.getCreatorId()).getName());
                question.setCreatorPhoto(reTeacher.get(question.getCreatorId()).getPicture());
            } else {
                log.debug("question.getRole() != 0");
                question.setCreatorName(reStudent.get(question.getCreatorId()).getName());
                question.setCreatorPhoto(reStudent.get(question.getCreatorId()).getAvatar());
            }

            //获取问题浏览量和回答量(返回值顺序和传入参数顺序一致)
            List<Long> counts = questionPvAnCountDao.getCount(question.getId(), questionPvAnCountDao.VIEWS, questionPvAnCountDao.ANSWER_COUNT);
            question.setPv(counts.get(0)); //绑定浏览量
            question.setAnswerCount(counts.get(1)); //绑定回答量
        }

        log.debug("问题列表");
        return page;
    }


    /**
     * 学生默认页获取统计信息
     *
     * @return map
     * @author lyj
     * @since 2015-4-2
     */
    public Map<String, Object> getCount(){
        if (webContext.getRole() != Roles.STUDENT){
            log.debug("学生默认页获取统计信息webContext.getRole() != Roles.STUDENT && webContext.getRole() != Roles.SUPER_ADMIN");
            log.warn("权限错误！");
            throw new ServiceException("权限错误！");
        }
        log.debug("学生默认页获取统计信息");
        return questionDao.getCount();
    }
}
